package com.gph.saviorframework.shiro.verification;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * Created by savior on 2016/8/29.
 * 验证码生成
 */
public class VerificationCodeGenerator {

    private static final int WIDTH = 100;//生成的图片的宽度
    private static final int HEIGHT = 35;//生成的图片的高度

    /**
     * 生成验证码图片和结果
     */
    public static void genCode(HttpServletRequest request,HttpServletResponse response)
            throws Exception{
        //1.在内存中创建一张图片
        BufferedImage bi = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        //2.得到图片
        Graphics g = bi.getGraphics();
        //3.设置图片的背影色
        setBackGround(g);
        //4.设置图片的边框
        //setBorder(g);
        //5.在图片上画干扰线
        drawRandomLine(g);
        //6.写在图片上随机数
        String result = drawRandomNum((Graphics2D) g);//根据客户端传递的createTypeFlag标识生成验证码图片
        //7.将随机数存在session中
        request.getSession().setAttribute("verificationCode", result);

        //8.设置响应头通知浏览器以图片的形式打开
        response.setContentType("image/jpeg");//等同于response.setHeader("Content-Type", "image/jpeg");
        //9.设置响应头控制浏览器不要缓存
        response.setDateHeader("expries", -1);
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        //10.将图片写给浏览器
        ImageIO.write(bi, "jpg", response.getOutputStream());
    }

    /**
     * 生成验证码图片和结果
     */
    public static void genCode(int width,int height,HttpServletRequest request,HttpServletResponse response)
            throws Exception{
        //1.在内存中创建一张图片
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //2.得到图片
        Graphics g = bi.getGraphics();
        //3.设置图片的背影色
        setBackGround(g);
        //4.设置图片的边框
        //setBorder(g);
        //5.在图片上画干扰线
        drawRandomLine(g);
        //6.写在图片上随机数
        String result = drawRandomNum((Graphics2D) g);//根据客户端传递的createTypeFlag标识生成验证码图片
        //7.将随机数存在session中
        request.getSession().setAttribute("checkcode", result);

        //8.设置响应头通知浏览器以图片的形式打开
        response.setContentType("image/jpeg");//等同于response.setHeader("Content-Type", "image/jpeg");
        //9.设置响应头控制浏览器不要缓存
        response.setDateHeader("expries", -1);
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        //10.将图片写给浏览器
        ImageIO.write(bi, "jpg", response.getOutputStream());
    }

    private static String drawRandomNum(Graphics2D g) {
        String result = "";
        String str = "";
        Random ra =new Random();
        int num1 = 0;
        int num2 = 0;
        int type = ra.nextInt(4);
        if(type == 2 || type == 3){
            num1 = ra.nextInt(10);
            num2 = ra.nextInt(10);
        }else{
            num1 = ra.nextInt(20);
            num2 = ra.nextInt(20);
        }
        if(type == 0){
            //加法运算
            result = num1 + num2 + "";
            str = num1 + "+" + num2;
        }else if(type == 1){
            //减法运算
            if(num1 >= num2){
                result = num1 - num2 + "";
                str = num1 + "-" + num2;
            }else{
                result = num2 - num1 + "";
                str = num2 + "-" + num1;
            }
        }else if(type == 2){
            //乘法运算
            result = num1 * num2 + "";
            str = num1 + "×" + num2;
        }else{
            //除法运算
            result = num1 + "";

            if (num2 == 0) {
                num2 = 1;
            }
            num1 = num1 * num2;
            str = num1 + "÷" + num2;
            System.out.println("=========>" + str);
        }
        // 设置颜色
        g.setColor(Color.RED);
        // 设置字体
        g.setFont(new Font("宋体", Font.BOLD, 20));
        createRandomChar(g,str);
        return result;
    }

    /**
     * 创建随机字符
     * @param g
     * @param baseChar
     * @return 随机字符
     */
    private static void createRandomChar(Graphics2D g,String baseChar) {
        int x = 5;
        String ch ="";
        // 控制字数
        for (int i = 0; i < baseChar.length(); i++) {
            // 设置字体旋转角度
            int degree = new Random().nextInt() % 30;
            ch = baseChar.charAt(i) + "";
            // 正向角度
            if(!ch.equals("+") && !ch.equals("-") && !ch.equals("÷") && !ch.equals("×")){
                g.rotate(degree * Math.PI / 180, x, 20);
            }
            g.drawString(ch, x, 18);
            // 反向角度

            if(!ch.equals("+") && !ch.equals("-") && !ch.equals("÷") && !ch.equals("×")){
                g.rotate(-degree * Math.PI / 180, x, 20);
            }
            x += 15;
        }

    }

    /**
     * 设置图片的背景色
     * @param g
     */
    private static void setBackGround(Graphics g) {
        // 设置颜色
        g.setColor(Color.WHITE);
        // 填充区域
        g.fillRect(0, 0, WIDTH, HEIGHT);
    }

    /**
     * 设置图片的边框
     * @param g
     */
    private static void setBorder(Graphics g) {
        // 设置边框颜色
        g.setColor(Color.BLUE);
        // 边框区域
        g.drawRect(1, 1, WIDTH - 2, HEIGHT - 2);
    }

    /**
     * 在图片上画随机线条
     * @param g
     */
    private static void drawRandomLine(Graphics g) {
        // 设置颜色
        g.setColor(Color.GREEN);
        // 设置线条个数并画线
        for (int i = 0; i < 10; i++) {
            int x1 = new Random().nextInt(WIDTH);
            int y1 = new Random().nextInt(HEIGHT);
            int x2 = new Random().nextInt(WIDTH);
            int y2 = new Random().nextInt(HEIGHT);
            g.drawLine(x1, y1, x2, y2);
        }
    }
}
